'use client';

import {
  type ChangeEvent,
  type FormEvent,
  useEffect,
  useRef,
  useState,
} from 'react';
import { useMutation } from '@tanstack/react-query';
import { updatePostStatus } from '@/services/api';
import diff from 'microdiff';
import type { IDifference, IQueryPostDetails } from '@/interfaces';
import type { TPostReviewState, TPostSortState, TPostState } from '@/types';
import useToast from '@/hooks/useToast';
import { getDiffData, getRandomIntInclusive } from '@/lib/tool';
import Box from '@/app/[locale]/admin/common/box';
import Spinner from '@/app/[locale]/component/spinner/spinner';
import type { PrefixedTTranslatedFields } from '@/lib/dictionaries';

export default function UpdatePostState({
  source,
  translatedFields,
}: {
  source: IQueryPostDetails;
  translatedFields: PrefixedTTranslatedFields<'postAdminPage'>;
}) {
  const { show } = useToast();
  const [form, setForm] = useState<{
    state: TPostState;
    reviewState: TPostReviewState;
    sortState: TPostSortState;
    compositeReason?: string;
    compositeRemark?: string;
    sortReason?: string;
    sortRemark?: string;
    secret?: string;
  }>({
    state: source.details.state,
    reviewState: source.details.reviewState,
    sortState: source.details.sortState,
    compositeReason: '',
    compositeRemark: '',
    sortReason: '',
    sortRemark: '',
    secret: '',
  });
  const [differenceData, setDifferenceData] = useState<IDifference[]>([]);
  const stateSelectRef = useRef<HTMLSelectElement>(null);
  const [isDisabledSave, setIsDisabledSave] = useState(true);

  const updatePostStatusMutation = useMutation(updatePostStatus);

  useEffect(() => {
    if (source) {
      const diffData = diff(
        {
          state: source.details.state,
          reviewState: source.details.reviewState,
          sortState: source.details.sortState,
          secret: '',
        },
        {
          state: form.state,
          reviewState: form.reviewState,
          sortState: form.sortState,
          secret: form.secret,
          compositeReason: form.compositeReason,
          compositeRemark: form.compositeRemark,
          sortReason: form.sortReason,
          sortRemark: form.sortRemark,
        },
      );
      setDifferenceData(diffData);
      setIsDisabledSave(diffData.length === 0);
    }
  }, [form, source]);

  async function onClickSave(e: FormEvent<HTMLFormElement>) {
    try {
      e.preventDefault();
      e.stopPropagation();

      const data = getDiffData(differenceData);
      setCompositeState(data);

      const id = source.basic.id;
      await updatePostStatusMutation.mutateAsync({
        id,
        data,
      });

      show({
        type: 'SUCCESS',
        message: translatedFields.saveCompleted,
      });
    } catch (e) {
      updatePostStatusMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    } finally {
      setDifferenceData([]);
    }
  }

  function setCompositeState(data: Record<string, any>) {
    const state: TPostState = data.state || null;
    const reviewState: TPostReviewState = data.reviewState;

    if (state && reviewState !== 'APPROVED') {
      stateSelectRef.current?.focus();
      throw translatedFields.invalidState;
    }

    let compositeState;
    if (state) {
      compositeState = state;
    } else if (reviewState) {
      compositeState = reviewState;
    }

    if (compositeState) {
      data.compositeState = compositeState;
    }

    delete data.state;
    delete data.reviewState;
  }

  function onClickRandomKey() {
    let secret = '';
    for (let i = 0; i < 4; i++) {
      secret += getRandomIntInclusive(0, 9) + '';
    }
    setForm({ ...form, secret });
  }

  function onChangeForm(
    e: ChangeEvent<HTMLSelectElement | HTMLInputElement | HTMLTextAreaElement>,
  ) {
    const name = e.target.name;
    const value = e.target.value;
    setForm({ ...form, [name]: value });
  }

  return (
    <Box>
      <form onSubmit={onClickSave} className="vstack gap-4">
        <div>
          <label className="form-label">{translatedFields.state}</label>
          <select
            ref={stateSelectRef}
            name="state"
            value={form.state}
            onChange={onChangeForm}
            className="form-select"
            aria-label="state"
            placeholder={translatedFields.statePlaceholder}
          >
            {['SHOW', 'HIDE', 'LOCK', 'CLOSE'].map((key) => {
              return (
                <option key={key} value={key}>
                  {(translatedFields as any).STATE[key]}
                </option>
              );
            })}
          </select>
        </div>

        {form.state === 'LOCK' && (
          <div>
            <label className="form-label">{translatedFields.secret}</label>
            <div className="input-group">
              <input
                type="text"
                className="form-control"
                name="secret"
                value={form.secret}
                onChange={onChangeForm}
                placeholder={translatedFields.secretPlaceholder}
              />
              <button
                onClick={onClickRandomKey}
                className="btn btn-outline-secondary"
                type="button"
              >
                {translatedFields.randomlyGenerated}
              </button>
            </div>
          </div>
        )}

        <div>
          <label className="form-label">{translatedFields.reviewState}</label>
          <select
            name="reviewState"
            value={form.reviewState}
            onChange={onChangeForm}
            className="form-select"
            aria-label="reviewState"
            placeholder={translatedFields.reviewStatePlaceholder}
          >
            {['APPROVED', 'DENIED', 'PENDING', 'CLOSE'].map((key) => {
              return (
                <option key={key} value={key}>
                  {(translatedFields as any).REVIEW_STATE[key]}
                </option>
              );
            })}
          </select>
        </div>

        <div className="row">
          <div className="col">
            <label className="form-label">
              {translatedFields.reviewHistoryPage.reason}
            </label>
            <textarea
              rows={1}
              className="form-control"
              name="compositeReason"
              value={form.compositeReason}
              onChange={onChangeForm}
              aria-describedby="compositeReason"
              placeholder={translatedFields.reviewHistoryPage.reasonPlaceholder}
            />
          </div>
          <div className="col">
            <label className="form-label">
              {translatedFields.reviewHistoryPage.remark}
            </label>
            <textarea
              rows={1}
              className="form-control"
              name="compositeRemark"
              value={form.compositeRemark}
              onChange={onChangeForm}
              aria-describedby="compositeRemark"
              placeholder={translatedFields.reviewHistoryPage.remarkPlaceholder}
            />
          </div>
        </div>

        <div>
          <label className="form-label">{translatedFields.sortState}</label>
          <select
            name="sortState"
            value={form.sortState}
            onChange={onChangeForm}
            className="form-select"
            aria-label="sortState"
            placeholder={translatedFields.sortStatePlaceholder}
          >
            {['GLOBAL', 'CURRENT', 'RECOMMEND', 'POPULAR', 'DEFAULT'].map(
              (key) => {
                return (
                  <option key={key} value={key}>
                    {(translatedFields as any).SORT_STATE[key]}
                  </option>
                );
              },
            )}
          </select>
        </div>

        <div className="row">
          <div className="col">
            <label className="form-label">
              {translatedFields.reviewHistoryPage.sortReason}
            </label>
            <textarea
              rows={1}
              className="form-control"
              name="sortReason"
              value={form.sortReason}
              onChange={onChangeForm}
              aria-describedby="sortReason"
              placeholder={
                translatedFields.reviewHistoryPage.sortReasonPlaceholder
              }
            />
          </div>
          <div className="col">
            <label className="form-label">
              {translatedFields.reviewHistoryPage.sortRemark}
            </label>
            <textarea
              rows={1}
              className="form-control"
              name="sortRemark"
              value={form.sortRemark}
              onChange={onChangeForm}
              aria-describedby="sortRemark"
              placeholder={
                translatedFields.reviewHistoryPage.sortRemarkPlaceholder
              }
            />
          </div>
        </div>

        <button
          type="submit"
          disabled={updatePostStatusMutation.isLoading || isDisabledSave}
          className="btn btn-success col col-lg-2 my-4"
        >
          {updatePostStatusMutation.isLoading && <Spinner classs="me-2" />}
          {translatedFields.update}
        </button>
      </form>
    </Box>
  );
}
